import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="Docs/Utils/CRUD" />

# CRUD Utils

## Upsert Node
The `upsertNode` function helps you insert a new
node between two other nodes.

The signature for this looks like:

```js
upsertNode(
  nodes: NodeData[],
  edges: EdgeData[],
  edge: EdgeData,
  newNode: NodeData
) => { nodes: NodeData[]; edges: EdgeData[]; }
```

Below is an example usage:

```js
import { upsertNode} from 'reaflow';

const id = `node-${Math.random()}`;
const newNode = {
  id,
  text: id
};

const results = upsertNode(nodes, edges, edge, newNode);
setNodes(results.nodes);
setEdges(results.edges);
```

## Remove Node
The `removeNode` function helps you remove a node
and all related edges.

The signature for this looks like:

```js
removeNode(
  nodes: NodeData[],
  edges: EdgeData[],
  removeNodes: string | string[]
) => { nodes: NodeData[]; edges: EdgeData[]; }
```

Below is an example usage:

```js
import { removeNode } from 'reaflow';

const results = removeNode(nodes, edges, nodeIds);
setNodes(results.nodes);
setEdges(results.edges);
```

## Node Removal and Upsert
The `removeAndUpsertNodes` helper allows you to remove a node
that has existing `to` and `from` edges and link the child
edges from the node remove to the parent of the node removed.

The signature for this looks like:

```js
removeAndUpsertNodes(
  nodes: NodeData[],
  edges: EdgeData[],
  removeNodes: NodeData | NodeData[],
  onNodeLinkCheck?: (
    newNodes: NodeData[],
    newEdges: EdgeData[],
    from: NodeData,
    to: NodeData,
    port?: PortData
  ) => undefined | boolean
) => { nodes: NodeData[]; edges: EdgeData[]; }
```

Below is an example usage:

```js
import { removeAndUpsertNodes } from 'reaflow';

const result = removeAndUpsertNodes(nodes, edges, node);
setNodes(results.nodes);
setEdges(results.edges);
```

## Add Node and Optional Edge
The `addNodeAndEdge` helper is a shortcut function to add a
node to a nodes array and a optional edge.

The signature for this looks like:

```js
addNodeAndEdge(
  nodes: NodeData[],
  edges: EdgeData[],
  node: NodeData,
  toNode?: NodeData
) => { nodes: NodeData[]; edges: EdgeData[]; }
```

Below is an example usage:

```js
import { addNodeAndEdge } from 'reaflow';

const result = addNodeAndEdge(
  nodes,
  edges,
  {
    id,
    text: id
  },
  enteredNode
);

setNodes(results.nodes);
setEdges(results.edges);
```

## Remove Edge
The `removeEdge` function simplifies removing a single
or array of edges.

The signature for this looks like:

```js
removeEdge(
  edges: EdgeData[],
  edge: EdgeData | EdgeData[]
) => EdgeData[]
```

Below is an example usage:

```js
import { removeEdge } from 'reaflow';

const newEdges = removeEdge(
  edges,
  edgesToRemove
);

setEdges(newEdges);
```

## Remove Edges from Node
The `removeEdgesFromNode` function simplifies removing all
edges from a node.

The signature for this looks like:

```js
removeEdgesFromNode(
  nodeId: string,
  edges: EdgeData[]
) => EdgeData[]
```

Below is an example usage:

```js
import { removeEdgesFromNode } from 'reaflow';

const newEdges = removeEdgesFromNode(
  node.id,
  edges
);

setEdges(newEdges);
```

## Create Edge from Nodes
The `createEdgeFromNodes` function simplifies creating an
edge between two nodes.

The signature for this looks like:

```js
createEdgeFromNodes(
  fromNode: NodeData,
  toNode: NodeData
) => EdgeData
```

Below is an example usage:

```js
import { createEdgeFromNodes } from 'reaflow';

const newEdge = createEdgeFromNodes(
  fromNode,
  toNode
);

setEdges([...edges, newEdge]);
```
